﻿#pragma execution_character_set("utf-8")
#include "communicatenormaldelegate.h"
#include "communicateupdatedelegate.h"
#include "../CommunicateDelegate/filedata.h"
#include "hmicommondefine.h"
#include "instructionEnum.h"
#ifdef BUILD_X86_WINDOWS
#include <windows.h>
#endif


#define D_Debug_flag 0
#define D_MAX_CONNECT_FAILED_COUNT 100

extern FileData fileData;




CommunicateUpdateDelegate::CommunicateUpdateDelegate()
{
    hmiCommunicate = new HmiCommunicate;

    hmiInitialStatusFlag = 0;

    qDebug()<<"init client_soap timer";
    timerOrder = new QTimer;
//    QObject::connect(timerOrder,SIGNAL(timeout()),this,SLOT(timeOrderWork()));//,Qt::BlockingQueuedConnection

    //不要用定时器，网络情况不好时，会有累计现象．

    reConnectCount = 0;


    //
//    maxTime2 = 0;
//    minTime2 = 100000000;
//    maxTime3 = 0;
//    minTime3 = 100000000;
//    pTime2 = 0;
//    pTime3 = 0;
//    p2 = 0;
//    p3 = 0;
}

CommunicateUpdateDelegate::~CommunicateUpdateDelegate()
{
    qDebug()<<"CommunicateUpdateDelegate::run() end";
    delete hmiCommunicate;
}

int CommunicateUpdateDelegate::setUserInfo(UserInfo userInfoIn)
{
    tmpUserInfo=userInfoIn;
    return 1;
}

void CommunicateUpdateDelegate::tryToConnect(QString hmiVersionInfo)
{
    hmiInitialStatusFlag = 0;    //开始(重新)初始化各项内容
}

int CommunicateUpdateDelegate::setUpdateTimerPeriod(int originUpdatePeriodIn,int maxUpdatePeriodIn,int deltaAdjustIn)
{
    minUpdatePeriod=originUpdatePeriodIn;
    maxUpdatePeriod=maxUpdatePeriodIn;
    deltaAdjust=deltaAdjustIn;
    currentUpdatePeriod=minUpdatePeriod;
    timerOrder->start(currentUpdatePeriod);
    return 1;
}



int CommunicateUpdateDelegate::getVMarkPositionInWorld(PositionInfo_hmi &positionReturn)
{
    int returnFlag;
    usingMutex.lock();
    if(soap_call_getVMarkPositionInWorld(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),""
                                     ,tmpUserInfo,positionReturn) == SOAP_OK)
    {
        isConnected=true;
        qDebug()<<"CommunicateNormalDelegate::getVMarkPositionInWorld = ok";
        returnFlag=1;
    }
    else
    {
        qDebug()<<"CommunicateNormalDelegate::getVMarkPositionInWorld  failed";
        isConnected=false;
        //qDebug("soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
        returnFlag=-1;
    }
    soap_destroy(&hmiCommunicate->client_soap);
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;

}

int CommunicateUpdateDelegate::getVehiclePosition_specified(int typeIn,
                                                            PositionInfo_hmi &positionReturn)
{
    int returnFlag;
    usingMutex.lock();
    if(soap_call_getVehiclePosition_specified(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),""
                                     ,tmpUserInfo,typeIn,positionReturn) == SOAP_OK)
    {
        isConnected=true;
        qDebug()<<"CommunicateNormalDelegate::getVehiclePosition_specified = ok";
        returnFlag=1;
    }
    else
    {
        qDebug()<<"CommunicateNormalDelegate::getVehiclePosition_specified  failed,typeIn"<<typeIn;
        isConnected=false;
        //qDebug("soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
        returnFlag=-1;
    }
    soap_destroy(&hmiCommunicate->client_soap);
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;
}



bool CommunicateUpdateDelegate::isConnectedStatus()
{
    return isConnected;
}

void CommunicateUpdateDelegate::updateTmpInfo(QString serverIP)
{
    usingMutex.lock();
//    tmpUserInfo.account = hmiCommunicate->globalData->userInfo.account;
//    tmpUserInfo.ip = hmiCommunicate->globalData->userInfo.ip;
//    tmpUserInfo.password = hmiCommunicate->globalData->userInfo.password;
//    tmpUserInfo.operationSystem = hmiCommunicate->globalData->userInfo.operationSystem;

    tmpUserInfo=hmiCommunicate->globalData->getUserInfo();
    tmpServerIp = serverIP;
    tmpServerIpArray = serverIP.toLatin1();
    usingMutex.unlock();

//    qDebug() << "CommunicateUpdateDelegate::updateTmpInfo tmpUserInfo.ip = " << QString::fromStdString(hmiCommunicate->globalData->userInfo.ip);
}

void CommunicateUpdateDelegate::timeOrderWork()
{
    //qDebug()<<"timeOrderWork()";
    if(D_Debug_flag)
    {
        qDebug()<<"timeOrderWork "<<tmpServerIp
               <<" controllerIsConnected"<<hmiCommunicate->globalData->controllerIsConnected;
    }
        if(hmiCommunicate->globalData)
        {
            if(D_Debug_flag)
            {
                qDebug()<<"hmiCommunicate->globalData";
            }
            //globalData数据指针已获取
            if(hmiCommunicate->globalData->controllerIsConnected != EM_CONNECT_SUCCESS)
            {
                if(D_Debug_flag)
                {
                    qDebug()<<"hmiCommunicate->globalData->controllerIsConnected != EM_CONNECT_SUCCESS";
                }
                //若连接不成功 或 断线
//                qDebug()<<"reConnectCount"<<reConnectCount;
                if(tmpServerIp != "")
                {
                    if(hmiCommunicate->globalData->globalLoginStatus)
                    {
                        //若已登陆:表示登陆状态下断线->重新尝试登陆
                        if(50 <= reConnectCount)//50*80 = 4000 - 4s
                        {
                            login_initial();

                        }
                        else
                        {
                               reConnectCount++;
                               usleep(50000);//50ms
                        }
                    }
                    else
                    {
                        login_initial();
                    }

                }

            }
            else
            {
                if(D_Debug_flag)
                {
                    qDebug()<<"else";
                }
               reConnectCount = 0;
                //已经登录而且链接正常
                if(tmpServerIp != "")
                {
//                    updateControllerInfo();
                    updateControllerInfo_oneshotTransmit();

                }
            }
        }

}

void CommunicateUpdateDelegate::updateControllerInfo()
{
    //判断控制器的初始化状态是否完成
    if(EM_UPDATE_STATUS_LV1 == hmiCommunicate->globalData->initCtrlState)
    {
        int result = getFunctionInitState();//合并gsoap传送
        if(-500==result)
        {
            return ;
        }
        //获取init返回值 同时mid那边会判断 调用透明膜or弹框
        hmiCommunicate->globalData->initCtrlState = result;
        if(EM_UPDATE_STATUS_LV2 == result)
        {
            qDebug()<<"*** *** updateFunctionInit : ok! *** ***";
            //允许进入LV1;
            hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV1;
        }
        else
        {
            //禁止进入LV1;继而禁止进入控制
            hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_FAIL;
        }
    }


    if(E_UPDATA_TYPE_COMMON == hmiCommunicate->globalData->ioUpdateFlag)
    {
        std::vector<Message > messageVectorOut;
        updateFunctionMessage(messageVectorOut);//合并gsoap传送
        hmiCommunicate->globalData->setMessageVector(messageVectorOut);
    }

    //LV1定时刷新;若切换了系统,需要重新跟新所有状态
    if(hmiCommunicate->globalData->gsoapCtrlState == EM_UPDATE_STATUS_LV1)//表示 当前Lv1
    {
        updateControllerInfo_lv1();

    }
    //LV2定时刷新;若切换了系统,需要重新跟新所有状态
    else if(hmiCommunicate->globalData->gsoapCtrlState == EM_UPDATE_STATUS_LV2)
    {
            if(E_UPDATA_TYPE_IO == hmiCommunicate->globalData->ioUpdateFlag)
            {
                UpdateDataLv3 updateDataLv3Out;
                if(1==updateControllerInfo_lv3(updateDataLv3Out))//合并gsoap传送
                {
                    hmiCommunicate->globalData->setUpdateLv3(updateDataLv3Out);
                }
            }
            else if(E_UPDATA_TYPE_COMMON == hmiCommunicate->globalData->ioUpdateFlag)
            {

                if(true==updateFunctionLV2_all())//合并gsoap传送
                {
                    updateControllerInfo_lv2SucessLogic();
                    lv2FalseCount = 0;      //异常累计清零

                }
                else//lv2 异常
                {
                    qDebug()<<"*** *** updateFunctionLV2 : false! *** ***";
                    lv2FalseCount++;
                    //连接状态 异常
                    if(lv2FalseCount == D_MAX_CONNECT_FAILED_COUNT)//5超过失败次数就提示断线。设置为３时２．５Ｇ网络很容易提示断线。
                    {
                        hmiCommunicate->globalData->controllerIsConnected = EM_CONNECT_ERROR;
                        hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV1;
                        lv2FalseCount = 0;      //异常累计清零
                        //异常归零部分数据
                        hmiCommunicate->globalData->globalCurrentState = ENUM_COMMAND_RESET;
                        hmiCommunicate->globalData->globalServoState = EM_MOTOR_STATUS_SERVO_OFF;
                    }
                }
            }

    }

}

void CommunicateUpdateDelegate::updateControllerInfo_oneshotTransmit()
{
    if(D_Debug_flag)
    {
        qDebug()<<"updateControllerInfo_oneshotTransmit initCtrlState"<<hmiCommunicate->globalData->initCtrlState;
    }
    bool isContainIoData=false;
    if(E_UPDATA_TYPE_IO == hmiCommunicate->ioData->ioUpdateFlag)
    {
        isContainIoData=true;
    }
    #ifdef D_FOR_DEMO
    isContainIoData=true;
    #endif
    bool isContainAgvData=true;
    bool isContainPointCloud=hmiCommunicate->globalData->isUpdatePointCloudStatus();

    struct ControllerInformationAll infoOut;
    getControllerAllInformation(isContainIoData,  isContainAgvData,isContainPointCloud,infoOut);

    if(false==infoOut.isReturnSucess)
    {
        qDebug()<<"*** *** updateControllerInfo_oneshotTransmit : failed! *** ***";
//        hmiInitialStatusFlag = 0;    //开始(重新)初始化各项内容.网络差时,会导致频繁更新lv1
        lv2FalseCount++;
        //连接状态 异常
        if(lv2FalseCount == D_MAX_CONNECT_FAILED_COUNT)//5超过失败次数就提示断线。设置为３时２．５Ｇ网络很容易提示断线。
        {
            hmiCommunicate->globalData->controllerIsConnected = EM_CONNECT_ERROR;
            hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV1;
            lv2FalseCount = 0;      //异常累计清零
            //异常归零部分数据
            hmiCommunicate->globalData->globalCurrentState = ENUM_COMMAND_RESET;
            hmiCommunicate->globalData->globalServoState = EM_MOTOR_STATUS_SERVO_OFF;
        }
        if(EM_UPDATE_STATUS_LV1 == hmiCommunicate->globalData->initCtrlState)
        {
            //禁止进入LV1;继而禁止进入控制
            hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_FAIL;
        }
        return ;
    }
    else
    {
        lv2FalseCount=0;

    }
    //判断控制器的初始化状态是否完成
    if(EM_UPDATE_STATUS_LV1 == hmiCommunicate->globalData->initCtrlState)
    {
        //获取init返回值 同时mid那边会判断 调用透明膜or弹框
        hmiCommunicate->globalData->initCtrlState = EM_UPDATE_STATUS_LV2;
        //允许进入LV1;
        hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV1;
        hmiCommunicate->globalData->setUpdateLv1(infoOut.dataLv1);


    }
    else if(EM_UPDATE_STATUS_LV2 == hmiCommunicate->globalData->initCtrlState)
    {
        hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV2;
        hmiCommunicate->globalData->setMessageVector(infoOut.messageVector);
        if(isContainIoData)
        {
                hmiCommunicate->ioData->setUpdateLv3(infoOut.dataLv3);
        }
        hmiCommunicate->ioData->setCurrentRobotId(infoOut.dataLv2.currentRobotID);

        hmiCommunicate->globalData->setUpdateLv1(infoOut.dataLv1);
        hmiCommunicate->globalData->setUpdateLv2(infoOut.dataLv2);
        hmiCommunicate->globalData->setVehicleBasicInfo(infoOut.dataLv2_agv);
        if(isContainPointCloud)
        {
              hmiCommunicate->globalData->setMapInfo(infoOut.pointCloud);
        }
        updateControllerInfo_lv2SucessLogic();

    }



}


bool CommunicateUpdateDelegate::updateDefaultFile(std::string &defaultUserFileOut)
{
    usingMutex.lock();
    std::string returnName;
    if(soap_call_readDefaultFileName(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",
                                     tmpUserInfo,returnName) == SOAP_OK)
    {
        //QString tmpDefaultName = QString::fromStdString(returnName);
        //qDebug()<<"***DefaultName*** :"<<tmpDefaultName;
        defaultUserFileOut=returnName;

    }
    else
    {
        soap_destroy(&hmiCommunicate->client_soap);
        soap_end(&hmiCommunicate->client_soap);
        soap_done(&hmiCommunicate->client_soap);
        usingMutex.unlock();
        return false;
        //qDebug("soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
    }
    soap_destroy(&hmiCommunicate->client_soap);
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return true;
}

void CommunicateUpdateDelegate::run()
{
    cycle_ns=currentUpdatePeriod*1000000;
    initialTime();
    forever
    {
#ifdef D_FOR_AGV
        wait_period();

        QTime startTime = QTime::currentTime();

        timeOrderWork();

        QTime stopTime = QTime::currentTime();
        int elapsed = startTime.msecsTo(stopTime);
        if(1)//Timers cannot be stopped from another thread
        {
//                        qDebug()<<"updateControllerInfo elapsed="<<elapsed;
            if(elapsed>currentUpdatePeriod && elapsed<maxUpdatePeriod)
            {
                currentUpdatePeriod+=deltaAdjust;
                qDebug()<<"timer+++ currentUpdatePeriod"<<currentUpdatePeriod;
            }
            else if(minUpdatePeriod<currentUpdatePeriod && elapsed<currentUpdatePeriod)
            {
                currentUpdatePeriod-=deltaAdjust;
                qDebug()<<"timer--- currentUpdatePeriod"<<currentUpdatePeriod;
            }
            else if( elapsed>maxUpdatePeriod)
            {
                currentUpdatePeriod=maxUpdatePeriod;

            }
            cycle_ns=currentUpdatePeriod*1000000;
//            qDebug()<<"updateControllerInfo elapsed="<<elapsed<<"ms currentUpdatePeriod"
//                   <<currentUpdatePeriod<<"cycle_ns"<<cycle_ns;

        }
#else
        msleep(250);
        timeOrderWork();
#endif

    }
}




#define NSEC_PER_SEC 1000000000


uint64_t timespec2ns(struct timespec timeSp)
{
    return timeSp.tv_sec * NSEC_PER_SEC + timeSp.tv_nsec;
}




timespec ns2timespec(uint64_t timeIn)
{
    timespec timeSp;
    timeSp.tv_sec=timeIn/NSEC_PER_SEC;
    timeSp.tv_nsec=timeIn%NSEC_PER_SEC;
    return timeSp;
}

void CommunicateUpdateDelegate::initialTime()
{
#ifndef BUILD_X86_WINDOWS
    struct timespec tmpTime;
    clock_gettime( CLOCK_MONOTONIC, &tmpTime );

    wakeup_time= timespec2ns(tmpTime);
#endif
}



void CommunicateUpdateDelegate::wait_period()
{
#ifndef BUILD_X86_WINDOWS
    // calc next wake time (in sys time)
    wakeup_time += cycle_ns;
    //如果当前时间超过了醒来时间，则醒来时间重新设定．
    struct timespec tmpTime;
    clock_gettime( CLOCK_MONOTONIC, &tmpTime );
    uint64_t currentTime= timespec2ns(tmpTime);
    if(currentTime>wakeup_time)
    {
        wakeup_time=currentTime;
//        qDebug()<<"网速太慢，滞后";
    }
    while (1)
    {
        struct timespec tmpTimeSleep=ns2timespec(wakeup_time);
        clock_nanosleep(CLOCK_MONOTONIC ,TIMER_ABSTIME, &tmpTimeSleep, NULL);
        break;
    }
#else
    Sleep(20); // 2000ms = 2s
#endif



}


int CommunicateUpdateDelegate::getControllerAllInformation( bool isContainIoData,
                                                           bool isContainAgvData, bool isContainPointCloud,
                                                           ControllerInformationAll &infoOut)
{
    usingMutex.lock();
    bool returnFlag;

    if(soap_call_getControllerAllInformation(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",
                           tmpUserInfo,isContainIoData,isContainAgvData,isContainPointCloud,infoOut) == SOAP_OK)
    {
        isConnected=true;
        returnFlag = true;
    }
    else
    {
        isConnected=false;
        if(D_Debug_flag)
        {
            qDebug("getControllerAllInformation:soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
        }

        returnFlag = false;
    }

    soap_destroy(&hmiCommunicate->client_soap);//注释掉会导致内存泄露，最后内存被爆满
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;
}

void CommunicateUpdateDelegate::login_initial()
{
//    qDebug()<<"*****login_initial******";
    int returnFLag = 0;
    usingMutex.lock();
    if(soap_call_getTcpConnectState(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",tmpUserInfo,returnFLag) == SOAP_OK)
    {
        if(returnFLag == 1)
        {
            hmiCommunicate->globalData->currentRobotID = 0;//重新初始化机器人信息(这个涉及文件地址获取)
            hmiInitialStatusFlag = 0;//重新初始化 时间 和 缺省状态 初始读文件状态

            fileData.initFileData();//重新初始化所有文件内容(编辑对象)

            hmiCommunicate->globalData->initCtrlState = EM_UPDATE_STATUS_LV1;
            hmiCommunicate->globalData->initHmiState = EM_UPDATE_STATUS_LV1;
            hmiCommunicate->globalData->controllerIsConnected = EM_CONNECT_SUCCESS;
            hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV1;//重新LV1
        }
    }
    usingMutex.unlock();
}

void CommunicateUpdateDelegate::updateControllerInfo_inial()
{

}

void CommunicateUpdateDelegate::updateControllerInfo_lv1()
{
        UpdateDataLv1 updateDataLv1Out;
        if(updateFunctionLV1(updateDataLv1Out))
        {
            qDebug()<<"*** *** updateFunctionLV1 : ok! *** ***";
            lv2FalseCount = 0;      //开始(重新)计数
            hmiInitialStatusFlag = 0;    //开始(重新)初始化各项内容
            hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV2;//表示 改变为lv2

//            hmiCommunicate->globalData->lock();
            hmiCommunicate->globalData->setUpdateLv1(updateDataLv1Out);
//            hmiCommunicate->globalData->unlock();
        }
        else
        {
            //连接状态 异常
            qDebug()<<"*** *** updateFunctionLV1 : failed! *** ***";
            hmiCommunicate->globalData->controllerIsConnected = EM_CONNECT_ERROR;
            hmiCommunicate->globalData->gsoapCtrlState = EM_UPDATE_STATUS_LV1;
        }


}

void CommunicateUpdateDelegate::updateControllerInfo_lv2SucessLogic()
{
    if(D_Debug_flag)
    {
        qDebug()<<"updateControllerInfo_lv2SucessLogic hmiInitialStatusFlag"<<hmiInitialStatusFlag;
    }
//    hmiCommunicate->globalData->lock();
    CurrentRunFile tmpcurrentRunFile;
    hmiCommunicate->globalData->getCurrentRunFile(tmpcurrentRunFile);
    int tmpRuningFileNameSize=tmpcurrentRunFile.runingFileName.size();
    QString currentRunningProgramName="";
    if(tmpcurrentRunFile.runingFileName.size()>0)
    {
        currentRunningProgramName== QString::fromStdString(tmpcurrentRunFile.runingFileName[0]);
    }
//    hmiCommunicate->globalData->unlock();

    if(hmiInitialStatusFlag < 15)
    {
        qDebug()<<"updateControllerInfo_lv2SucessLogic hmiInitialStatusFlag"<<hmiInitialStatusFlag;
    }

    if(hmiInitialStatusFlag >= 15)
    {
        //初始化已经全部完成
        if(tmpRuningFileNameSize>0 &&
                (hmiCommunicate->globalData->globalCurrentState == ENUM_COMMAND_RESET ||
                 hmiCommunicate->globalData->globalCurrentState == ENUM_COMMAND_END))
        {
            hmiCommunicate->globalData->initHmiState = EM_UPDATE_STATUS_LV2;

            //if(defaultName !=  currentName)
            if(hmiInitialStatusFlag == 15)
            {

                //发生改变
                if(fileData.currentFileName != currentRunningProgramName && currentRunningProgramName != "")
                {
                    qDebug()<<"fileData.currentFileName"<<fileData.currentFileName
                           <<"currentRunningProgramName"<<currentRunningProgramName;
                    hmiInitialStatusFlag++;
                }

            }
            else// 16
            {
                hmiInitialStatusFlag++;

                if(hmiInitialStatusFlag == 40)//25 * 80 ms
                {

                    if(fileData.readAllowFlag)//hmiTimeInitFlag == 20 等待 到允许 写
                    {
                        qDebug()<<"*******************";
                        qDebug()<<"change =====fileName====="<<fileData.currentFileName;
                        qDebug()<<"change =====commName====="<<currentRunningProgramName;
                        hmiInitialStatusFlag = 15;
                        qDebug()<<"change =====changeEnd=====";
                        qDebug()<<"*******************";
                    }
                    else
                    {
                        hmiInitialStatusFlag = 16;
                    }



                }
            }
        }
        //若是自己打开文件readAllowFlag == false 不需要刷这部分
    }
    else if(hmiInitialStatusFlag < 10)
    {
        //缓冲期
        hmiInitialStatusFlag++;//to 10
    }
    else if(10 == hmiInitialStatusFlag)
    {
        hmiCommunicate->globalData->initHmiState = -1;//2017.05.22

        //时间问题:设置arm系统时间
        QString tmp = QString::fromStdString(hmiCommunicate->globalData->getCurrentTime());
        //qDebug()<<"updateFunctionLV2() init ********"<<tmp;

        QString pattern("\\s*(\\d+)-(\\d+)-(\\d+)\\s+(\\d+):(\\d+):(\\d+)\\s*");
        QRegExp rx(pattern);
        int pos = tmp.indexOf(rx);
        if ( pos >= 0 )
        {
            tmp = "date -s " +
                    rx.cap(1)+"."+rx.cap(2)+"."+rx.cap(3)+"-"+
                    rx.cap(4)+":"+rx.cap(5)+":"+rx.cap(6);
            qDebug()<<"updateFunctionLV2() init ********set time="<<tmp;

            QByteArray cmd;
            cmd = tmp.toLatin1();
            #ifdef BUILD_ARM
            system(cmd.data());
//            system("/bin/app_pwm");
            #endif
        }

        hmiInitialStatusFlag++;//to 11
    }
    else if(11 == hmiInitialStatusFlag)
    {
        hmiCommunicate->globalData->initHmiState = -2;
        //坐标系问题:获取坐标系所有数据
        std::vector<HmiToolCoordinateInformation > recvToolCoordinateOut;
        std::vector<HmiUserCoordinateInformation > recvUserCoordinateOut;
        if(updateCoordInfo(recvToolCoordinateOut,recvUserCoordinateOut))
        {
            hmiCommunicate->globalData->setCoordinateInfo(recvToolCoordinateOut,
                                                          recvUserCoordinateOut);

        }

        hmiInitialStatusFlag++;//to 12
    }
    else if(12 == hmiInitialStatusFlag)
    {
        updateControllerInfo_defaultProgramFile();

    }
    else if(13 == hmiInitialStatusFlag)
    {
        updateControllerInfo_ioInitial();
    }
    else if(14 == hmiInitialStatusFlag)
    {
        //mount问题:更新profile tree update
        emit proFileViewInitSignal();
        qDebug()<<"updateFunctionLV2() init ********file tree";

        hmiInitialStatusFlag++;//to else
        //所有的东西初始化完成了 2017.05.03
        hmiCommunicate->globalData->initHmiState = EM_UPDATE_STATUS_LV2;
    }
    else
    {}
}

int CommunicateUpdateDelegate::updateControllerInfo_lv3(UpdateDataLv3 &updateDataLv3Out)
{
    if(0 == hmiInitialStatusFlag)
    {
        UpdateDataLv3 tmpupdateDataLv3;
        if(!updateFunctionLV3(tmpupdateDataLv3))
        {
            qDebug()<<"*** *** updateFunctionLV3 : false! *** ***";
            //是否需要什么提示?
            hmiInitialStatusFlag ++;
        }
        else
        {
            updateDataLv3Out=tmpupdateDataLv3;
            return 1;
        }
    }
    else
    {
        hmiInitialStatusFlag++;
        if(10 == hmiInitialStatusFlag)//400*10 4000-4
        {
            hmiInitialStatusFlag = 0;
        }
    }
    return 0;
}

void CommunicateUpdateDelegate::updateControllerInfo_defaultProgramFile()
{


    CurrentRunFile tmpcurrentRunFile;
    hmiCommunicate->globalData->getCurrentRunFile(tmpcurrentRunFile);
    int runningFileNameSize=tmpcurrentRunFile.runingFileName.size();
    QString runningFileName0="";
    if(tmpcurrentRunFile.runingFileName.size()>0)
    {
        runningFileName0 = QString::fromStdString(tmpcurrentRunFile.runingFileName[0]);
    }
    hmiCommunicate->globalData->initHmiState = -4;//2017.05.22

    if( runningFileNameSize> 0)//打开当前文件
    {

        if(runningFileName0 != "")
        {
            qDebug()<<"updateFunctionLV2() init ********open currentRunFile.Name:"<<runningFileName0;

            if(1!=fileData.readProgram(runningFileName0))
            {
                qDebug()<<"failed! get program file";
                return ;
            }
            fileData.cmdStrWriteSuccess = true;//runview的更新
            emit editProgramSignal();//通知 程序编辑

        }
        else
        {
            qDebug()<<"failed! runningFileName0 is null !!!";
            return ;
        }
    }
    hmiInitialStatusFlag++;//to 13

}


int CommunicateUpdateDelegate::gsoapGetAllIONamesInfo(QVector<QVector<QString> > &ioMsgData)
{

    ioMsgData.resize(7);
    struct IOMapNamesInfo ioNamesInfoList;
    int returnFlag;
    communicateNormalDelegate->getAllIoNamesinfo(hmiCommunicate->globalData->currentRobotID, ioNamesInfoList, returnFlag);
    if(returnFlag == 0)
    {
        qDebug() << "CommunicateUpdateDelegate::gsoapGetAllIONamesInfo ==== Success!";

        if(!ioNamesInfoList.diNamesInfo.empty())
        {
            // DI
            for(int i = 0; i < (int)ioNamesInfoList.diNamesInfo.size(); i++)
            {
                ioMsgData[IO_TYPE_DI].append(QString::fromStdString(ioNamesInfoList.diNamesInfo.at(i)));
            }

        }

        if(!ioNamesInfoList.doNamesInfo.empty())
        {
            // DO
            for(int i = 0; i < (int)ioNamesInfoList.doNamesInfo.size(); i++)
            {
                ioMsgData[IO_TYPE_DO].append(QString::fromStdString(ioNamesInfoList.doNamesInfo.at(i)));
            }
        }

        if(!ioNamesInfoList.aiNamesInfo.empty())
        {
            // AI
            for(int i = 0; i < (int)ioNamesInfoList.aiNamesInfo.size(); i++)
            {
                ioMsgData[IO_TYPE_AI].append(QString::fromStdString(ioNamesInfoList.aiNamesInfo.at(i)));
            }
        }

        if(!ioNamesInfoList.aoNamesInfo.empty())
        {
            // AO
            for(int i = 0; i < (int)ioNamesInfoList.aoNamesInfo.size(); i++)
            {
                ioMsgData[IO_TYPE_AO].append(QString::fromStdString(ioNamesInfoList.aoNamesInfo.at(i)));
            }
        }

        if(!ioNamesInfoList.siNamesInfo.empty())
        {
            // SI
            for(int i = 0; i < (int)ioNamesInfoList.siNamesInfo.size(); i++)
            {
                ioMsgData[IO_TYPE_SI].append(QString::fromStdString(ioNamesInfoList.siNamesInfo.at(i)));
            }
        }

        if(!ioNamesInfoList.soNamesInfo.empty())
        {
            // SO
            for(int i = 0; i < (int)ioNamesInfoList.soNamesInfo.size(); i++)
            {
                ioMsgData[IO_TYPE_SO].append(QString::fromStdString(ioNamesInfoList.soNamesInfo.at(i)));
            }
        }
    }
    else
    {
        qDebug() << "CommunicateUpdateDelegate::gsoapGetAllIONamesInfo ==== Success!";
        return -1;
    }

    return 0;
}

bool CommunicateUpdateDelegate::updateCoordInfo(std::vector<HmiToolCoordinateInformation > &recvToolCoordinateOut,
                                                std::vector<HmiUserCoordinateInformation > &recvUserCoordinateOut)
{
    usingMutex.lock();
    bool returnFlag;
    std::vector<HmiToolCoordinateInformation > recvToolCoordinate;
    if(soap_call_getToolCoordinateInformation(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",
                                             tmpUserInfo,hmiCommunicate->globalData->currentRobotID,recvToolCoordinate) == SOAP_OK)
    {

        recvToolCoordinateOut=recvToolCoordinate;

    }
    else
    {
        soap_destroy(&hmiCommunicate->client_soap);
        soap_end(&hmiCommunicate->client_soap);
        soap_done(&hmiCommunicate->client_soap);
        usingMutex.unlock();
        return false;
    }
    soap_destroy(&hmiCommunicate->client_soap);
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);

    std::vector<HmiUserCoordinateInformation > recvUserCoordinate;
    if(soap_call_getUserCoordinateInformation(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",
                                         tmpUserInfo,hmiCommunicate->globalData->currentRobotID,recvUserCoordinate) == SOAP_OK)
    {
        recvUserCoordinateOut=recvUserCoordinate;

    }
    else
    {
        soap_destroy(&hmiCommunicate->client_soap);
        soap_end(&hmiCommunicate->client_soap);
        soap_done(&hmiCommunicate->client_soap);
        usingMutex.unlock();
        return false;
        //qDebug("soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
    }
    soap_destroy(&hmiCommunicate->client_soap);
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return true;
}

int CommunicateUpdateDelegate::getFunctionInitState()
{
    usingMutex.lock();
    int returnFlag = EM_UPDATE_STATUS_LV1;
    if(soap_call_initControllerStatus(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",
                                      tmpUserInfo,returnFlag) == SOAP_OK)
    {
        returnFlag = EM_UPDATE_STATUS_LV2;
    }
    else
    {
        qDebug("getFunctionInitState():soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
        returnFlag = -500;
    }
    soap_destroy(&hmiCommunicate->client_soap);//必须
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;
}

bool CommunicateUpdateDelegate::updateFunctionMessage(std::vector<Message > &messageVectorOut)
{
    usingMutex.lock();
    std::vector<Message > tmpMessage;
    bool returnFlag;
    if(soap_call_updateControllerMessage(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",
                                         tmpUserInfo,tmpMessage) == SOAP_OK)
    {
        returnFlag = true;
        messageVectorOut=tmpMessage;
    }
    else
    {
        //qDebug("Msg:soap error:%d,%s,%s", client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
        returnFlag = false;
    }

    soap_destroy(&hmiCommunicate->client_soap);//必须
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;
}

bool CommunicateUpdateDelegate::updateFunctionLV1(UpdateDataLv1 &updateDataLv1Out)
{
    usingMutex.lock();
    struct UpdateDataLv1 updateDataLv1;
    bool returnFlag;

    if(soap_call_updateControllerInfoLevel1(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",tmpUserInfo,hmiCommunicate->globalData->currentRobotID,updateDataLv1) == SOAP_OK)
    //if(soap_call_updateControllerInfoLevel1(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",tmpUserInfo,1,updateDataLv1) == SOAP_OK)
    {

        updateDataLv1Out=updateDataLv1;


        returnFlag = true;
    }
    else
    {
//        qDebug("lv1:soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
        returnFlag = false;
    }

    soap_destroy(&hmiCommunicate->client_soap);//必须
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;
}

bool CommunicateUpdateDelegate::updateFunctionLV2(UpdateDataLv2 &updateDataLv2Out)
{
//    return true;
//    qDebug() << "CommunicateUpdateDelegate::updateFunctionLV2 " ;
    usingMutex.lock();
    bool returnFlag;
    struct UpdateDataLv2 updateDataLv2;
    int tmpFlag=soap_call_updateControllerInfoLevel2(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",tmpUserInfo,updateDataLv2) ;
    if(tmpFlag == SOAP_OK)
    {
//        qDebug()<<"CommunicateUpdateDelegate::updateFunctionLV2 sucess";

        isConnected=true;
        updateDataLv2Out=updateDataLv2;

        returnFlag = true;

    }
    else
    {
        //没有接硬件的时候会报SOAP_TYPE错误。
        qDebug() << "CommunicateUpdateDelegate::updateFunctionLV2 returnFlag:" << tmpFlag;
        isConnected=false;
        qDebug("lv2:soap error:%d,%s,%s", hmiCommunicate->client_soap.error,
               *soap_faultcode(&hmiCommunicate->client_soap),
                                    *soap_faultstring(&hmiCommunicate->client_soap) );
        returnFlag = false;
    }


    soap_destroy(&hmiCommunicate->client_soap);//必须
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;
}

bool CommunicateUpdateDelegate::updateFunctionLV2_all()
{
    //test--------------------
//    updateFunctionLV2();
//    updateFunctionLV2_agv();
//    updateFunctionLV2_vehiclePositionsInfo();
//    updateFunctionLV2_singlePositions();
//    return true;

    //gsoap的调用函数，引用的参数在控制器函数里面必须赋值，否则可能导致ｓopetype 错误。
    UpdateDataLv2 updateDataLv2Out;
    VehicleBasicInfo vehicleInfoOut;
    if(true==updateFunctionLV2(updateDataLv2Out) && true==updateFunctionLV2_agv(vehicleInfoOut))//lv2 正常
    {

        std::vector<PointCloudData_3D> pointCloudOut;
        if(hmiCommunicate->globalData->isUpdatePointCloudStatus())
        {
              getAllPointCloud_translated(pointCloudOut);//1个ｔim561需要消耗1.5MBit/s
        }


//        hmiCommunicate->globalData->lock();
        hmiCommunicate->globalData->setUpdateLv2(updateDataLv2Out);
        hmiCommunicate->globalData->setVehicleBasicInfo(vehicleInfoOut);
        if(hmiCommunicate->globalData->isUpdatePointCloudStatus())
        {
              hmiCommunicate->globalData->setMapInfo(pointCloudOut);
        }
//        hmiCommunicate->globalData->unlock();
//        qDebug()<<"updateFunctionLV2_all = ok";//gsoap test

        return true;
    }
    else
    {
        qDebug()<<"updateFunctionLV2_all = failed";

    }

    return false;

}

bool CommunicateUpdateDelegate::updateFunctionLV2_agv(VehicleBasicInfo &vehicleInfoOut)
{
    //    return true;
//        qDebug() << "CommunicateUpdateDelegate::updateFunctionLV2_agv " ;
        usingMutex.lock();
        bool returnFlag;
        struct VehicleBasicInfo updateDataLv2;
        int tmpFlag=soap_call_updateControllerInfoLevel2_agv(&hmiCommunicate->client_soap,
                                     (const char*)tmpServerIpArray.data(),"",tmpUserInfo,updateDataLv2) ;
        if(tmpFlag == SOAP_OK)
        {
//            qDebug()<<"CommunicateUpdateDelegate::updateFunctionLV2_agv sucess";
    //        hmiCommunicate->globalData->lock();//为什么会出现死锁（和获取当前程序之间）,调用者加锁了
            isConnected=true;

          vehicleInfoOut=updateDataLv2;

            returnFlag = true;

    //        hmiCommunicate->globalData->unlock();
        }
        else
        {
            //没有接硬件的时候会报SOAP_TYPE错误。
            qDebug() << "CommunicateUpdateDelegate::updateFunctionLV2_agv returnFlag:" << tmpFlag;
            isConnected=false;
    //        qDebug("lv2:soap error:%d,%s,%s", hmiCommunicate->client_soap.error,
    //               *soap_faultcode(&hmiCommunicate->client_soap),
    //                                    *soap_faultstring(&hmiCommunicate->client_soap) );
            returnFlag = false;
        }


        soap_destroy(&hmiCommunicate->client_soap);//必须
        soap_end(&hmiCommunicate->client_soap);
        soap_done(&hmiCommunicate->client_soap);
        usingMutex.unlock();
        return returnFlag;
}


int CommunicateUpdateDelegate::getCurrentMapName(std::string &mapNameOut)
{
    usingMutex.lock();
    if(soap_call_getCurrentMapName(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),""
                                     ,tmpUserInfo,mapNameOut) == SOAP_OK)
    {
        isConnected=true;
//        qDebug()<<"CommunicateNormalDelegate::getCurrentMapName = ok";
    }
    else
    {
        isConnected=false;
        //qDebug("soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
    }
    soap_destroy(&hmiCommunicate->client_soap);
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return isConnected;
}

int CommunicateUpdateDelegate::getAllPointCloud_translated(std::vector<PointCloudData_3D> &pointCloudOut)
{
    usingMutex.lock();
    if(soap_call_getAllPointCloud_translated(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),""
                                     ,tmpUserInfo,pointCloudOut) == SOAP_OK)
    {
        isConnected=true;
//        qDebug()<<"CommunicateNormalDelegate::getAllPointCloud_translated = ok";
    }
    else
    {
        isConnected=false;
//        qDebug("getAllPointCloud_translated soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
    }
    soap_destroy(&hmiCommunicate->client_soap);
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return isConnected;
}

//bool CommunicateUpdateDelegate::updateFunctionLV2_singlePositions()
//{
//    int tmpKey1,tmpKey2,tmpKey3,tmpKey4,tmpKey5;
//    tmpKey5=getVehiclePosition_specified(10,hmiCommunicate->globalData->vehicleInCU1);
//    tmpKey1=getVMarkPositionInWorld(hmiCommunicate->globalData->vmarkInWorld);
//    tmpKey2=getVehiclePosition_specified(6,hmiCommunicate->globalData->vehicleInVmark);
//    tmpKey3=getVehiclePosition_specified(9,hmiCommunicate->globalData->vehicleInQrcode);
//    tmpKey4=getVehiclePosition_specified(1,hmiCommunicate->globalData->vehicleInWorld);

//    if(1!=tmpKey1 || 1!=tmpKey2 || 1!=tmpKey3 || 1!=tmpKey4 || 1!=tmpKey5 )
//    {
//        return false;
//    }
//    return true;
//}

//bool CommunicateUpdateDelegate::updateFunctionLV2_vehiclePositionsInfo()
//{
//    //    return true;
//        qDebug() << "CommunicateUpdateDelegate::updateFunctionLV2_vehiclePositionsInfo " ;
//        usingMutex.lock();
//        bool returnFlag;
//        VehiclePositionsInfo updateDataLv2;
//        int tmpFlag=soap_call_updateControllerInfoLevel2_positions(&hmiCommunicate->client_soap,
//                                     (const char*)tmpServerIpArray.data(),"",tmpUserInfo,updateDataLv2) ;
//        if(tmpFlag == SOAP_OK)
//        {
//            qDebug()<<"CommunicateUpdateDelegate::updateFunctionLV2_vehiclePositionsInfo sucess";
//    //        hmiCommunicate->globalData->lock();//为什么会出现死锁（和获取当前程序之间）,调用者加锁了
//            isConnected=true;

//            //agv
//            hmiCommunicate->globalData->vmarkInWorld=updateDataLv2.vmarkInWorld;
//            hmiCommunicate->globalData->vehicleInVmark=updateDataLv2.vehicleInVmark;
//            hmiCommunicate->globalData->vehicleInQrcode=updateDataLv2.vehicleInQrcode;
//            hmiCommunicate->globalData->vehicleInCU1=updateDataLv2.vehicleInCU1;
//            hmiCommunicate->globalData->vehicleInWorld=updateDataLv2.vehicleInWorld;

//            returnFlag = true;

//    //        hmiCommunicate->globalData->unlock();
//        }
//        else
//        {
//            //没有接硬件的时候会报SOAP_TYPE错误。
//            qDebug() << "CommunicateUpdateDelegate::updateFunctionLV2_vehiclePositionsInfo returnFlag:" << tmpFlag;
//            isConnected=false;
//    //        qDebug("lv2:soap error:%d,%s,%s", hmiCommunicate->client_soap.error,
//    //               *soap_faultcode(&hmiCommunicate->client_soap),
//    //                                    *soap_faultstring(&hmiCommunicate->client_soap) );
//            returnFlag = false;
//        }


//        soap_destroy(&hmiCommunicate->client_soap);//必须
//        soap_end(&hmiCommunicate->client_soap);
//        soap_done(&hmiCommunicate->client_soap);
//        usingMutex.unlock();
//        return returnFlag;
//}

bool CommunicateUpdateDelegate::updateFunctionLV3(UpdateDataLv3 &updateDataLv3Out)
{
    usingMutex.lock();
    bool returnFlag;
    struct UpdateDataLv3 updateDataLv3;

    if(soap_call_updateControllerInfoLevel3(&hmiCommunicate->client_soap,(const char*)tmpServerIpArray.data(),"",
                                            tmpUserInfo,updateDataLv3) == SOAP_OK)
    {
        updateDataLv3Out=updateDataLv3;
        qDebug()<<"updateFunctionLV3 = ok";
        //qDebug()<< QString::fromStdString(hmiCommunicate->globalData->powerOnTime);

        returnFlag = true;
    }
    else
    {
        qDebug("updateFunctionLV3 soap error:%d,%s,%s", hmiCommunicate->client_soap.error, *soap_faultcode(&hmiCommunicate->client_soap), *soap_faultstring(&hmiCommunicate->client_soap) );
        returnFlag = false;
    }

    soap_destroy(&hmiCommunicate->client_soap);//必须
    soap_end(&hmiCommunicate->client_soap);
    soap_done(&hmiCommunicate->client_soap);
    usingMutex.unlock();
    return returnFlag;
}

void CommunicateUpdateDelegate::updateControllerInfo_ioInitial()
{
    hmiCommunicate->globalData->initHmiState = -5;//2017.05.22

    qDebug()<<"updateFunctionLV2() init ******** iomap";

    //IO问题:初始化定义
    emit ioViewInitSignal();//初始化

    fileData.ioMsgData.clear();
    // GSOAP 获取iomap文件数据
    if(GSOAP_OPERATE_PROGRAM_FILE_SWITCH)
    {
        // 获取所有IO注释
        gsoapGetAllIONamesInfo(fileData.ioMsgData);
    }
    else
    {

        // 获取注释
        fileData.xmlParse.openXml(fileData.currentRobotFileAddress+"config/iomap.xml");
        // 获取IOMap子节点数据
        fileData.xmlParse.getAllIoList(fileData.ioMsgData);
        fileData.xmlParse.closeReadXml();

    }


    hmiInitialStatusFlag++;//to 14

}

